Skip to content

[공통] SonarCloud 연동 및 Claude Code AI 파이프라인 하네스 구성#1236

Merged
dooohun merged 3 commits into
developfrom
chore/sonarcloud-integration
Apr 21, 2026
Merged

[공통] SonarCloud 연동 및 Claude Code AI 파이프라인 하네스 구성#1236
dooohun merged 3 commits into
developfrom
chore/sonarcloud-integration

Conversation

@dooohun
Copy link
Copy Markdown
Contributor

@dooohun dooohun commented Apr 21, 2026

What is this PR? 🔍

  • 기능 : SonarCloud 정적 분석 CI 연동 + Claude Code AI 파이프라인 하네스 구성

Changes 📝

SonarCloud 연동

  • sonar-project.properties 추가 — SonarCloud 프로젝트 설정 (projectKey: BCSDLab_KOIN_WEB_RECODE, organization: bcsdlab)
  • .github/workflows/sonarcloud.yml 추가 — develop/main 브랜치 push 및 PR 시 정적 분석 자동 실행

Claude Code AI 파이프라인 하네스

  • .claude/CLAUDE.md 개선 — 영어→한국어 전면 재작성, 스킬과의 중복 제거 (224줄 → 75줄)
  • .gitignore — AI 파이프라인 중간 산출물 디렉토리(_workspace/) 추가
  • .claude/agents/ — 6개 에이전트 정의 추가
    • sonarcloud-analyzer : SonarCloud 이슈 조회 및 분류
    • code-quality-fixer : 이슈 기반 코드 품질 자동 수정
    • feature-planner : 기능 구현 계획 수립
    • feature-implementer : 기능 코드 작성
    • qa-reviewer : 코드 검증
    • pr-creator : GitHub PR 생성
  • .claude/skills/ — 7개 스킬 추가
    • koin-pipeline : 전체 파이프라인 오케스트레이터
    • sonarcloud-analysis : SonarCloud API 호출 가이드
    • code-quality-fix : KOIN 컨벤션 기반 수정 패턴
    • feature-planning : 아키텍처 설계 가이드
    • feature-implementation : KOIN 코드 패턴
    • qa-review : 검증 체크리스트
    • github-pr-creation : PR 생성 가이드

ScreenShot 📷

해당 없음 (CI 설정 및 Claude Code 설정)

Precaution

  • SonarCloud 분석 실행을 위해 GitHub Secrets에 SONAR_TOKEN 등록 필요 (완료)
  • Claude Code AI 파이프라인은 koin-pipeline 스킬 트리거 시 동작 ("SonarCloud 분석해줘", "기능 구현해줘" 등)

✔️ Please check if the PR fulfills these requirements

  • It's submitted to the correct branch, not the develop branch unconditionally?
  • If on a hotfix branch, ensure it targets main?
  • There are no warning message when you run yarn lint

Summary by CodeRabbit

릴리스 노트

  • Chores

    • SonarCloud 통합 구성 및 GitHub Actions 워크플로우 추가
    • 프로젝트 문서 구조 재정리 및 개발 가이드라인 업데이트
    • 작업 공간 디렉토리를 Git 추적 대상에서 제외
  • Documentation

    • 에이전트 및 기술 사양 문서 확대 (코드 품질, 기능 구현, QA 검증 프로세스)

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 21, 2026

Warning

Rate limit exceeded

@dooohun has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 2 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 48 minutes and 2 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 60e25a27-c65e-43b1-b4aa-ef746ccd8f69

📥 Commits

Reviewing files that changed from the base of the PR and between 99018f3 and cbdbd1b.

📒 Files selected for processing (5)
  • .claude/agents/code-quality-fixer.md
  • .claude/agents/pr-creator.md
  • .claude/agents/qa-reviewer.md
  • .claude/agents/sonarcloud-analyzer.md
  • .claude/skills/koin-pipeline/SKILL.md

Walkthrough

KOIN 프로젝트의 AI 에이전트 기반 자동화 파이프라인 구축을 위한 광범위한 문서 및 설정 파일이 추가되었습니다. SonarCloud 코드 품질 분석, 기능 구현 자동화, QA 검증, PR 생성 등을 수행하는 에이전트 스펙과 이를 지원하는 스킬 문서, 그리고 필수 설정 파일들이 새로 도입되었습니다.

Changes

Cohort / File(s) Summary
Guide 및 설정 문서
.claude/CLAUDE.md, sonar-project.properties, .gitignore
저장소 작업 가이드를 규정 중심으로 재작성하고, SonarCloud 프로젝트 설정 파일 및 워크스페이스 디렉토리 무시 규칙 추가.
에이전트 스펙
.claude/agents/sonarcloud-analyzer.md, .claude/agents/code-quality-fixer.md, .claude/agents/feature-planner.md, .claude/agents/feature-implementer.md, .claude/agents/qa-reviewer.md, .claude/agents/pr-creator.md
SonarCloud 이슈 분석, 코드 품질 수정, 기능 계획, 기능 구현, QA 검증, PR 생성 등 6가지 자동화 에이전트 워크플로우 정의.
스킬 문서
.claude/skills/sonarcloud-analysis/SKILL.md, .claude/skills/code-quality-fix/SKILL.md, .claude/skills/feature-planning/SKILL.md, .claude/skills/feature-implementation/SKILL.md, .claude/skills/qa-review/SKILL.md, .claude/skills/github-pr-creation/SKILL.md, .claude/skills/koin-pipeline/SKILL.md
각 에이전트가 수행하는 작업의 구체적 기술 명세서로, 패턴, 검증 체크리스트, 템플릿 코드 포함.
SonarCloud 설정 가이드
.claude/skills/sonarcloud-analysis/references/sonarcloud-setup.md
SonarCloud 조직/프로젝트 구성, sonar-project.properties 작성, GitHub Actions 워크플로우 예제 제공.
GitHub Actions 워크플로우
.github/workflows/sonarcloud.yml
푸시 및 PR 이벤트 시 SonarCloud 분석을 자동으로 실행하는 워크플로우 추가.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

⚙ Setting

Suggested reviewers

  • JeongWon-CHO
  • ff1451
  • dh2906
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 SonarCloud 연동과 Claude Code AI 파이프라인 하네스 구성이라는 주요 변경사항을 명확하게 요약하며, 실제 변경 내용과 일치합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/sonarcloud-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dooohun dooohun self-assigned this Apr 21, 2026
@dooohun dooohun added the 🌏 Deploy 배포 관련 사항 label Apr 21, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

🧹 Nitpick comments (4)
.github/workflows/sonarcloud.yml (1)

23-24: CI 설치 단계에서 --immutable 플래그 명시 권장

Line 24의 yarn 실행 시 --immutable 플래그를 명시적으로 지정하면 lockfile 무결성을 보장할 수 있습니다. Yarn Berry에서는 CI 환경(CI=true)에서 기본적으로 immutable 모드가 활성화되지만, 명시적 지정으로 의도를 명확히 하고 더 안정적인 빌드를 보장합니다.

🔧 제안 수정
      - name: Install package
-       run: yarn
+       run: yarn install --immutable
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/sonarcloud.yml around lines 23 - 24, In the GitHub Actions
CI step named "Install package" (the step that currently runs the `yarn`
command) change the command to explicitly include the immutable flag by
replacing the plain `yarn` invocation with `yarn --immutable` so the lockfile
integrity is enforced in CI; ensure the step that runs `yarn` uses the
`--immutable` flag to make the intent explicit and guarantee reproducible
installs.
.claude/skills/sonarcloud-analysis/SKILL.md (1)

26-29: “페이지네이션 포함” 설명과 예시 커맨드가 맞지 않습니다.

Line 26은 페이지네이션 포함이라고 되어 있지만 예시는 단일 호출만 보여줍니다. p 증가 루프(또는 total 기반 반복) 예시를 추가하면 실행 오해를 줄일 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/sonarcloud-analysis/SKILL.md around lines 26 - 29, The
documentation claims "페이지네이션 포함" but the example only shows a single curl call;
update SKILL.md to show how to paginate using the curl example by demonstrating
the `p` (page) parameter (and `ps` page size) in a loop or a total-based repeat;
reference the existing curl command and explain incrementing `p` (or checking
`total`/`paging` in the JSON) until all issues are retrieved so readers can run
multiple requests to collect every page.
.claude/agents/qa-reviewer.md (2)

44-44: "주요 사용자 인터랙션" 기준을 구체화하는 것을 고려하세요.

현재 "주요 사용자 인터랙션에 useLogger() 존재"라는 체크리스트 항목은 주관적이어서 자동 검증이 어려울 수 있습니다. 다음과 같이 구체화하면 QA 에이전트의 판단 일관성이 높아집니다:

  • 버튼 클릭 이벤트 핸들러
  • 폼 제출 핸들러
  • 모달/다이얼로그 열기/닫기
  • 탭/페이지 전환

이미 명확한 기준이 있다면 무시하셔도 됩니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/qa-reviewer.md at line 44, The checklist item "주요 사용자 인터랙션에
`useLogger()` 존재" is too vague; update the entry in qa-reviewer.md to enumerate
concrete interaction types so QA can auto-verify: replace the single checkbox
with specific sub-items such as "버튼 클릭 이벤트 핸들러에 `useLogger()` 적용", "폼 제출 핸들러에
`useLogger()` 적용", "모달/다이얼로그 열기·닫기에서 `useLogger()` 사용", and "탭/페이지 전환 시
`useLogger()` 적용" and keep the original `useLogger()` wording so reviewers can
match the symbol exactly.

54-70: 출력 스키마의 타입 정보를 더 명확히 하는 것을 고려하세요.

현재 JSON 예시는 명확하지만, 일부 필드의 타입이나 선택성이 명시되지 않았습니다:

  • line: number (예시로는 42)
  • suggestion: string (항상 필수인지, optional인지 불명확)
  • issues: 빈 배열 가능 여부

TypeScript 인터페이스 스타일로 주석을 추가하면 구현 시 혼란을 줄일 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/qa-reviewer.md around lines 54 - 70, Add a TypeScript-style
interface comment to the `_workspace/03_qa_result.json` output schema that
documents each field's type and optionality (e.g., lint_passed: boolean,
approved: boolean, summary: string, issues: Array<Issue> where Issue has
severity: string, file: string, line?: number, message: string, suggestion?:
string), explicitly note that `issues` can be an empty array, and clarify which
fields like `line` and `suggestion` are optional vs required so consumers of the
QA output (e.g., readers of `_workspace/03_qa_result.json`) have an unambiguous
contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/agents/code-quality-fixer.md:
- Around line 28-30: Specify clear retry semantics for the orchestration
contract: document input parameters for retry (batch range or specific batch
IDs), and define the merge strategy for result keys
`_workspace/01_analyzer_issues.json` fields `fixed`, `failed`, `skipped`, and
`changed_files` (options: accumulate/union, overwrite, or last-run-only),
include idempotency guarantees (how duplicate runs are detected and ignored),
and add an explicit "reset" flag or versioning to force overwrite when desired;
update the contract text around `_workspace/01_analyzer_issues.json` to state
these rules and reference the keys `fixed`, `failed`, `skipped`, `changed_files`
so QA can deterministically merge or replace results on retries.

In @.claude/agents/pr-creator.md:
- Around line 76-82: 출력 스키마에 실패 케이스가 빠져 있어서 오케스트레이터가 성공/실패를 구분할 수 없으니, 현재 JSON
예시(예: the object containing "pr_url","branch","commit_sha") 옆에 실패 응답 스키마를 추가해
주세요; 구체적으로 출력 스키마에 success:boolean, error:string (열거값: "QA_NOT_APPROVED" |
"GIT_PUSH_FAILED" | "PR_CREATE_FAILED"), message:string(구체적 에러 메시지),
details:object(추가 정보)을 포함시키고 에러 발생 시 해당 구조를 반환하도록 문서/예시를 갱신하세요.
- Line 20: 명확하지 않은 "작업 원칙 6"의 동작을 다음처럼 규정하세요: 동일 브랜치에 기존 PR이 있으면 새로운 PR은 생성하지 않고
기존 PR의 URL을 반환하되, 에이전트는 필요시 브랜치에 커밋은 푸시(pushCommits)하되 PR의 제목/본문은 수정하지
않습니다(unless updatePR flag is true). 즉, createPR는 호출하지 않고 existingPR을 반환하고,
updatePR은 명시적 플래그가 있을 때만 실행되도록 PR 생성/업데이트 흐름(createPR, updatePR, pushCommits)을
문서에 명시해 주세요.
- Line 72: 문서의 "PR 타입: `quality-fix` 또는 `feature`" 항목이 어디서 오는지 명시되어 있지 않으니,
.claude/agents/pr-creator.md의 해당 항목을 수정해 PR 타입 입력의 출처와 전달방식을 명확히 기재하세요; 예를 들어
"PR 타입(prType)은 오케스트레이터 스킬 koin-pipeline에서 agent 호출 시 입력 파라미터로 전달된다"라고 명시하고, 입력
파라미터 이름(prType), 허용값(`quality-fix`, `feature`), 그리고 수신 코드(예: generatePR 함수 또는
PRCreator agent의 입력 스키마)에서 이를 검증하는 방식(기본값/검증 에러 처리)을 간단히 기술하도록 변경하세요.

In @.claude/agents/qa-reviewer.md:
- Line 76: 출력 스키마(현재 54-70줄)에 누락된 `notes` 필드를 추가하세요: 스키마에 "notes" : { "type":
"string", "description": "파일 건너뜀 등 추가 정보(선택적)" } 형태로 정의하고 기본값/옵셔널로 처리하며, 스키마를
사용하는 검증/직렬화 로직(예: QA 응답 생성/예시 JSON)과 예제 출력(제시된 "파일 src/missing.ts를 찾을 수 없어 건너뜀"
문구)을 함께 갱신해 `notes`가 실제로 포함될 수 있도록 하세요.
- Line 16: Clarify the "점진적 검증" principle in the sentence "검증은 전체 완성 후 한 번이 아니라,
수정된 파일 단위로 점진적으로 수행한다" by specifying scope and process: change it to state that
validations run per change-set/commit (not literally per single file), describe
dependency-aware behavior (e.g., when API types or hooks change, run
dependent-unit and integration tests), and define "점진적" as validating
independent changes first and then running broader integration checks for
dependent files; alternatively provide an explicit removal instruction if you
prefer to drop the principle.

In @.claude/agents/sonarcloud-analyzer.md:
- Around line 18-19: Update the batch constraints in the sonarcloud-analyzer.md
guidance so it matches the sonarcloud-analysis skill contract: locate the list
item that reads "파일당 이슈 수가 많은 경우, 한 번에 처리할 수 있는 범위(파일 10개 이내)로 배치를 나눈다." and add
the missing constraint "배치당 최대 이슈 50개 (sonarcloud-analysis 제약)" so both the
analyzer and fixers use the same batching rule; ensure the phrase
'sonarcloud-analysis' and '배치당 최대 이슈 50개' appear together in that section to
make the contract explicit.

In @.claude/CLAUDE.md:
- Around line 71-74: 현재 문서의 "**변경 이력:**" 섹션에 있는 Markdown 표(| 날짜 | 변경 내용 | 대상 |
사유 | ...)가 앞뒤에 빈 줄이 없어 markdownlint MD058 경고가 발생합니다; 해당 표를 찾을 때는 "**변경 이력:**" 헤더
또는 표 시작 행("| 날짜 | 변경 내용 | 대상 | 사유 |")를 기준으로 표 바로 위에 한 줄, 표 바로 아래에 한 줄의 빈 줄을 추가해
주세요.

In @.claude/skills/github-pr-creation/SKILL.md:
- Around line 37-43: Add a language identifier to the fenced code block that
contains the commit message examples (the block starting with "feat: [기능명] 추가"
and including "fix:", "refactor:", "style:", "chore:") to satisfy markdownlint
MD040; edit the fence to start with ```text (or ```bash) so the code block
language is explicitly specified.

In @.claude/skills/koin-pipeline/SKILL.md:
- Line 191: The documentation currently instructs setting SONAR_HOST_URL
alongside SONAR_TOKEN but other docs state SONAR_HOST_URL is unnecessary for
SonarCloud; update SKILL.md to match that standard by removing the
SONAR_HOST_URL requirement or clarifying that only SONAR_TOKEN is needed for
SonarCloud usage. Find the section that mentions SONAR_HOST_URL and SONAR_TOKEN
and either delete the SONAR_HOST_URL entry or change its wording to indicate it
is only required for self-hosted SonarQube (keep SONAR_TOKEN as the required env
var), and ensure the wording matches other project docs for consistency.
- Line 20: The doc currently shows the move command "mv _workspace/
_workspace_prev/" which can fail or overwrite when _workspace_prev exists;
update the instructions to handle that case by choosing a safe rename policy
(e.g., append a timestamp or incrementing suffix) or explicitly remove/archive
the existing folder first; revise the SKILL.md text at the line containing "mv
_workspace/ _workspace_prev/" to describe the chosen behavior (timestamped
archive like _workspace_prev_YYYYMMDD_HHMMSS or a deterministic cleanup step)
and state the failure/overwrite semantics so users know whether the command will
fail, overwrite, or create a new timestamped directory.
- Line 82: Update the retry loop in the SKILL pipeline step(s) labeled
"approved: false" and the A-2 re-run path to explicitly track and increment a
retry counter (e.g., retry_count) in the step contract, stop retrying after 2
attempts, and include the list of P0 issues in the payload passed into the A-2
re-execution (so the re-run receives the P0 issue list); ensure this contract
change is applied to every occurrence referenced (the loop/step definitions
around the existing "approved: false" entries and the A-2 re-run logic mentioned
at lines 82, 151 and 174) so infinite or invalid retries are prevented and the
A-2 run receives P0 data.

In @.claude/skills/qa-review/SKILL.md:
- Around line 53-56: The check title "절대 경로 임포트 확인" and the grep pattern `grep
-n "from '\.\./" src/[changed-path]` are inconsistent; either update the title
to "상대 경로 임포트 확인" to match the `from '../` pattern, or change the grep pattern
to search for absolute imports (e.g., a pattern matching `from 'src/` or `from
'@/`) to match the "절대 경로 임포트 확인" intent; update the string literal in the
SKILL.md snippet so the title and the grep pattern refer to the same import
style.
- Around line 25-29: Replace the problematic invocation "yarn dlx tsc --noEmit"
(shown in the SKILL.md snippet) with a fixed-dependencies invocation: either use
"yarn exec tsc --noEmit" or "npx tsc --noEmit", or add a "tsc": "tsc" script to
package.json and run that (e.g., "yarn tsc --noEmit"); update the SKILL.md
example to show the chosen command so CI/local typechecks use the repo's locked
TypeScript version instead of dlx.

In @.claude/skills/sonarcloud-analysis/references/sonarcloud-setup.md:
- Line 64: Replace the non-deterministic reference
SonarSource/sonarcloud-github-action@master with a pinned commit SHA (e.g.,
SonarSource/sonarcloud-github-action@<commit-sha>) to ensure immutable workflow
execution; locate the `uses: SonarSource/sonarcloud-github-action@master` entry
and swap the tag for a specific commit SHA, and consider updating the workflow
to use the newer `SonarSource/sonarqube-scan-action` in the long term since the
current action is deprecated.

In @.claude/skills/sonarcloud-analysis/SKILL.md:
- Around line 15-16: 예시값 SONAR_PROJECT_KEY의 불일치 문제: 현재 샘플 값 "koin_web_recode"를
프로젝트에서 통용되는 키 규칙으로 통일된 값인 "BCSDLab_KOIN_WEB_RECODE"로 변경하고, SONAR_PROJECT_KEY를
참조하는 다른 문서(예: setup 문서, sonar-project.properties)와 동일하게 맞춰 동기화하세요; 해당 키를 사용하는 모든
설정/스크립트에서 변수 이름(SONAR_PROJECT_KEY)과 값이 일치하는지 확인해 수정하면 API 조회 실패를 방지할 수 있습니다.

---

Nitpick comments:
In @.claude/agents/qa-reviewer.md:
- Line 44: The checklist item "주요 사용자 인터랙션에 `useLogger()` 존재" is too vague;
update the entry in qa-reviewer.md to enumerate concrete interaction types so QA
can auto-verify: replace the single checkbox with specific sub-items such as "버튼
클릭 이벤트 핸들러에 `useLogger()` 적용", "폼 제출 핸들러에 `useLogger()` 적용", "모달/다이얼로그 열기·닫기에서
`useLogger()` 사용", and "탭/페이지 전환 시 `useLogger()` 적용" and keep the original
`useLogger()` wording so reviewers can match the symbol exactly.
- Around line 54-70: Add a TypeScript-style interface comment to the
`_workspace/03_qa_result.json` output schema that documents each field's type
and optionality (e.g., lint_passed: boolean, approved: boolean, summary: string,
issues: Array<Issue> where Issue has severity: string, file: string, line?:
number, message: string, suggestion?: string), explicitly note that `issues` can
be an empty array, and clarify which fields like `line` and `suggestion` are
optional vs required so consumers of the QA output (e.g., readers of
`_workspace/03_qa_result.json`) have an unambiguous contract.

In @.claude/skills/sonarcloud-analysis/SKILL.md:
- Around line 26-29: The documentation claims "페이지네이션 포함" but the example only
shows a single curl call; update SKILL.md to show how to paginate using the curl
example by demonstrating the `p` (page) parameter (and `ps` page size) in a loop
or a total-based repeat; reference the existing curl command and explain
incrementing `p` (or checking `total`/`paging` in the JSON) until all issues are
retrieved so readers can run multiple requests to collect every page.

In @.github/workflows/sonarcloud.yml:
- Around line 23-24: In the GitHub Actions CI step named "Install package" (the
step that currently runs the `yarn` command) change the command to explicitly
include the immutable flag by replacing the plain `yarn` invocation with `yarn
--immutable` so the lockfile integrity is enforced in CI; ensure the step that
runs `yarn` uses the `--immutable` flag to make the intent explicit and
guarantee reproducible installs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aa193ca0-d961-4e99-a082-bdb402e2cade

📥 Commits

Reviewing files that changed from the base of the PR and between 74dfd13 and 99018f3.

📒 Files selected for processing (18)
  • .claude/CLAUDE.md
  • .claude/agents/code-quality-fixer.md
  • .claude/agents/feature-implementer.md
  • .claude/agents/feature-planner.md
  • .claude/agents/pr-creator.md
  • .claude/agents/qa-reviewer.md
  • .claude/agents/sonarcloud-analyzer.md
  • .claude/skills/code-quality-fix/SKILL.md
  • .claude/skills/feature-implementation/SKILL.md
  • .claude/skills/feature-planning/SKILL.md
  • .claude/skills/github-pr-creation/SKILL.md
  • .claude/skills/koin-pipeline/SKILL.md
  • .claude/skills/qa-review/SKILL.md
  • .claude/skills/sonarcloud-analysis/SKILL.md
  • .claude/skills/sonarcloud-analysis/references/sonarcloud-setup.md
  • .github/workflows/sonarcloud.yml
  • .gitignore
  • sonar-project.properties

Comment on lines +28 to +30
- `_workspace/01_analyzer_issues.json` (sonarcloud-analyzer 출력)
- 처리할 배치 번호 (없으면 배치 1부터 순차 처리)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

재실행(리트라이) 시 상태 처리 규칙을 명시해 주세요.

현재 계약은 1회 실행 기준으로만 보이며(Line 28-30, 33-47), 오케스트레이터 재호출 시 fixed/failed/skipped/changed_files를 누적할지 덮어쓸지 정의가 없습니다. 재실행 정책(입력 배치 범위, 결과 병합 방식, 멱등성)을 명시해야 QA 루프에서 결과 왜곡을 막을 수 있습니다.

Also applies to: 33-47, 51-54

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/code-quality-fixer.md around lines 28 - 30, Specify clear
retry semantics for the orchestration contract: document input parameters for
retry (batch range or specific batch IDs), and define the merge strategy for
result keys `_workspace/01_analyzer_issues.json` fields `fixed`, `failed`,
`skipped`, and `changed_files` (options: accumulate/union, overwrite, or
last-run-only), include idempotency guarantees (how duplicate runs are detected
and ignored), and add an explicit "reset" flag or versioning to force overwrite
when desired; update the contract text around
`_workspace/01_analyzer_issues.json` to state these rules and reference the keys
`fixed`, `failed`, `skipped`, `changed_files` so QA can deterministically merge
or replace results on retries.

3. 브랜치는 `develop`에서 분기한다.
4. 커밋 메시지는 컨벤셔널 커밋 형식을 따른다.
5. PR 본문은 한국어로 작성한다 (KOIN PR 리뷰 규칙).
6. 기존 PR 체크 후, 동일 브랜치에 PR이 이미 있으면 업데이트하지 않고 링크를 반환한다.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

작업 원칙 6번의 동작을 명확히 하세요.

"동일 브랜치에 PR이 이미 있으면 업데이트하지 않고 링크를 반환한다"는 설명이 모호합니다:

  • 새로운 코드 변경사항을 브랜치에 푸시할지 여부가 불명확합니다
  • 일반적으로 동일 브랜치에 새 커밋을 푸시하면 기존 PR이 자동으로 업데이트됩니다
  • 현재 설명으로는 "아무것도 하지 않고 기존 PR 링크만 반환"하는 것인지, "새 커밋을 푸시하되 PR 본문은 수정하지 않는다"는 의미인지 알 수 없습니다

에이전트가 정확히 어떻게 동작해야 하는지 명시해주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/pr-creator.md at line 20, 명확하지 않은 "작업 원칙 6"의 동작을 다음처럼 규정하세요:
동일 브랜치에 기존 PR이 있으면 새로운 PR은 생성하지 않고 기존 PR의 URL을 반환하되, 에이전트는 필요시 브랜치에 커밋은
푸시(pushCommits)하되 PR의 제목/본문은 수정하지 않습니다(unless updatePR flag is true). 즉,
createPR는 호출하지 않고 existingPR을 반환하고, updatePR은 명시적 플래그가 있을 때만 실행되도록 PR 생성/업데이트
흐름(createPR, updatePR, pushCommits)을 문서에 명시해 주세요.


- `_workspace/03_qa_result.json` (qa-reviewer 출력)
- `_workspace/02_fixer_result.json` 또는 `_workspace/02_implementer_result.json`
- PR 타입: `quality-fix` 또는 `feature`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

PR 타입 입력의 출처를 명시하세요.

입력으로 "PR 타입: quality-fix 또는 feature"를 받는다고 했는데, 이 값이 어디서 전달되는지 명시되지 않았습니다. 오케스트레이터 스킬(koin-pipeline)에서 전달하는 것으로 추정되지만, 에이전트 스펙에서 명확히 해주면 구현 시 혼란을 줄일 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/pr-creator.md at line 72, 문서의 "PR 타입: `quality-fix` 또는
`feature`" 항목이 어디서 오는지 명시되어 있지 않으니, .claude/agents/pr-creator.md의 해당 항목을 수정해 PR
타입 입력의 출처와 전달방식을 명확히 기재하세요; 예를 들어 "PR 타입(prType)은 오케스트레이터 스킬 koin-pipeline에서
agent 호출 시 입력 파라미터로 전달된다"라고 명시하고, 입력 파라미터 이름(prType), 허용값(`quality-fix`,
`feature`), 그리고 수신 코드(예: generatePR 함수 또는 PRCreator agent의 입력 스키마)에서 이를 검증하는
방식(기본값/검증 에러 처리)을 간단히 기술하도록 변경하세요.

Comment on lines +76 to +82
```json
{
"pr_url": "https://github.com/BCSDLab/KOIN_WEB_RECODE/pull/NNN",
"branch": "feature/...",
"commit_sha": "abc123"
}
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

출력 스키마에 에러 상태 필드가 누락되었습니다.

현재 출력 스키마는 성공 케이스만 정의되어 있지만, 에러 핸들링 섹션(84-88줄)에서는 3가지 실패 케이스를 명시했습니다:

  • QA 미승인
  • git push 실패
  • PR 생성 실패

에이전트가 실패 시 출력해야 할 JSON 구조가 정의되지 않아, 오케스트레이터가 성공/실패를 구분할 수 없습니다.

다음과 같은 구조를 추가하세요:

{
  "success": false,
  "error": "QA_NOT_APPROVED | GIT_PUSH_FAILED | PR_CREATE_FAILED",
  "message": "구체적인 에러 메시지",
  "details": { /* 추가 정보 */ }
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/pr-creator.md around lines 76 - 82, 출력 스키마에 실패 케이스가 빠져 있어서
오케스트레이터가 성공/실패를 구분할 수 없으니, 현재 JSON 예시(예: the object containing
"pr_url","branch","commit_sha") 옆에 실패 응답 스키마를 추가해 주세요; 구체적으로 출력 스키마에
success:boolean, error:string (열거값: "QA_NOT_APPROVED" | "GIT_PUSH_FAILED" |
"PR_CREATE_FAILED"), message:string(구체적 에러 메시지), details:object(추가 정보)을 포함시키고 에러
발생 시 해당 구조를 반환하도록 문서/예시를 갱신하세요.

## 작업 원칙

1. `qa-review` 스킬을 로딩하여 검증 체크리스트를 확인한다.
2. 검증은 전체 완성 후 한 번이 아니라, 수정된 파일 단위로 점진적으로 수행한다.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

"점진적 검증" 원칙을 명확히 하세요.

"수정된 파일 단위로 점진적으로 수행한다"는 원칙이 모호합니다:

  • 파일 간 의존성이 있는 경우 (예: API 타입 변경 + 훅 변경) 개별 파일만으로는 검증이 불가능합니다
  • "점진적"이 "파일을 하나씩 순회하며 검증"을 의미하는지, "일부 파일만 먼저 검증 가능"을 의미하는지 불명확합니다

실제 검증 프로세스를 반영하도록 수정하거나, 원칙을 제거하는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/agents/qa-reviewer.md at line 16, Clarify the "점진적 검증" principle in
the sentence "검증은 전체 완성 후 한 번이 아니라, 수정된 파일 단위로 점진적으로 수행한다" by specifying scope
and process: change it to state that validations run per change-set/commit (not
literally per single file), describe dependency-aware behavior (e.g., when API
types or hooks change, run dependent-unit and integration tests), and define
"점진적" as validating independent changes first and then running broader
integration checks for dependent files; alternatively provide an explicit
removal instruction if you prefer to drop the principle.

## 테스트 시나리오

### 정상 흐름 (파이프라인 A)
1. `SONAR_HOST_URL`, `SONAR_TOKEN` 환경변수 설정
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

환경변수 안내가 문서 간 불일치합니다.

Line 191은 SONAR_HOST_URL 설정을 정상 흐름 전제로 안내하지만, 다른 문서에서는 SonarCloud에서 불필요하다고 명시합니다. 여기서도 동일 기준으로 통일해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/koin-pipeline/SKILL.md at line 191, The documentation
currently instructs setting SONAR_HOST_URL alongside SONAR_TOKEN but other docs
state SONAR_HOST_URL is unnecessary for SonarCloud; update SKILL.md to match
that standard by removing the SONAR_HOST_URL requirement or clarifying that only
SONAR_TOKEN is needed for SonarCloud usage. Find the section that mentions
SONAR_HOST_URL and SONAR_TOKEN and either delete the SONAR_HOST_URL entry or
change its wording to indicate it is only required for self-hosted SonarQube
(keep SONAR_TOKEN as the required env var), and ensure the wording matches other
project docs for consistency.

Comment on lines +25 to +29
# KOIN 프로젝트는 tsc를 단독 script로 노출하지 않음
# package.json의 build 스크립트(tsc && next build)를 활용하거나
# node_modules 내 tsc를 직접 호출
yarn dlx tsc --noEmit 2>&1 | head -50
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 목적: 리포지토리의 TypeScript 고정 실행 경로가 있는지 확인
set -e

echo "== package.json scripts 중 tsc 관련 =="
cat package.json | jq '.scripts'

echo "== typescript 의존성 확인 =="
cat package.json | jq '.devDependencies.typescript, .dependencies.typescript'

echo "== lockfile에 typescript 버전 존재 여부 =="
if [ -f yarn.lock ]; then
  rg -n "^typescript@" yarn.lock -n -A2 -B1 | head -40
else
  echo "yarn.lock 없음"
fi

Repository: BCSDLab/KOIN_WEB_RECODE

Length of output: 575


🏁 Script executed:

find . -name "SKILL.md" -type f 2>/dev/null | head -10

Repository: BCSDLab/KOIN_WEB_RECODE

Length of output: 368


🏁 Script executed:

# Check if the file exists and show the content around lines 25-29
if [ -f ".claude/skills/qa-review/SKILL.md" ]; then
  echo "=== File found. Content around lines 20-35 ==="
  sed -n '20,35p' ".claude/skills/qa-review/SKILL.md"
else
  echo "File not found at .claude/skills/qa-review/SKILL.md"
  echo "Searching for SKILL.md files..."
  find . -name "SKILL.md" 2>/dev/null
fi

Repository: BCSDLab/KOIN_WEB_RECODE

Length of output: 400


🏁 Script executed:

# Check alternative ways to run tsc with yarn
echo "=== Checking yarn exec tsc availability ==="
cat package.json | jq '.scripts | keys[] | select(contains("tsc"))'

echo ""
echo "=== Checking if node_modules has tsc binary ==="
ls -la node_modules/.bin/tsc 2>/dev/null || echo "node_modules/.bin/tsc not found (expected in non-build environment)"

echo ""
echo "=== Recommended approaches to run pinned tsc ==="
echo "1. yarn exec tsc (Yarn native way to run pinned dependencies)"
echo "2. npx tsc (npm's way using pinned version)"
echo "3. Add a script to package.json"

Repository: BCSDLab/KOIN_WEB_RECODE

Length of output: 415


yarn dlx tsc는 리포지토리의 고정된 TypeScript 버전을 무시할 수 있습니다.

Line 25-29의 yarn dlx tsc 방식은 실행 시점 최신 TypeScript를 받을 수 있어, 프로젝트 lockfile 기준 타입체크 결과와 달라질 수 있습니다. 고정된 의존성 버전 실행 방식으로 통일하려면:

  • yarn exec tsc 또는 npx tsc (권장)
  • 또는 package.jsontsc 스크립트 추가 ("tsc": "tsc")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/qa-review/SKILL.md around lines 25 - 29, Replace the
problematic invocation "yarn dlx tsc --noEmit" (shown in the SKILL.md snippet)
with a fixed-dependencies invocation: either use "yarn exec tsc --noEmit" or
"npx tsc --noEmit", or add a "tsc": "tsc" script to package.json and run that
(e.g., "yarn tsc --noEmit"); update the SKILL.md example to show the chosen
command so CI/local typechecks use the repo's locked TypeScript version instead
of dlx.

Comment on lines +53 to +56
**절대 경로 임포트 확인:**
```bash
grep -n "from '\.\./" src/[changed-path]
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

검증 항목 제목과 grep 패턴 의미가 서로 다릅니다.

Line 53의 “절대 경로 임포트 확인”인데 Line 55 패턴은 from '../(상대 경로)를 찾고 있습니다. 제목/패턴 중 하나를 의도에 맞게 정정해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/qa-review/SKILL.md around lines 53 - 56, The check title "절대
경로 임포트 확인" and the grep pattern `grep -n "from '\.\./" src/[changed-path]` are
inconsistent; either update the title to "상대 경로 임포트 확인" to match the `from '../`
pattern, or change the grep pattern to search for absolute imports (e.g., a
pattern matching `from 'src/` or `from '@/`) to match the "절대 경로 임포트 확인" intent;
update the string literal in the SKILL.md snippet so the title and the grep
pattern refer to the same import style.

run: yarn install

- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

What is the currently recommended way to pin SonarSource/sonarcloud-github-action in GitHub Actions: branch, tag, or commit SHA?

💡 Result:

The SonarSource/sonarcloud-github-action is deprecated and archived as of October 2025. SonarSource recommends migrating to SonarSource/sonarqube-scan-action, which is the current official action for SonarCloud scans. For pinning the sonarcloud-github-action (if still using the legacy version), official examples use tags like @v4.0.0 or @. The releases page shows tagged versions up to v5.0.0. However, GitHub's current security best practice (as of 2026) is to pin third-party actions to a full-length commit SHA for immutability and supply chain security. Tags are mutable (repository owners can update what they point to), while SHAs are fixed. SonarSource's own repositories demonstrate pinning other actions to SHAs (e.g., updating gh-action_release to specific commits). General sources confirm SHA pinning as the recommended method over tags or branches. To pin: Find the full SHA for the desired release tag on the repository's tags page (e.g., https://github.com/SonarSource/sonarcloud-github-action/releases/tag/v5.0.0), then use: uses: SonarSource/sonarcloud-github-action@ Branch pinning (e.g., @master) is not recommended as branches are highly mutable.

Citations:


🌐 Web query:

GitHub Actions best practices for pinning SonarSource sonarcloud-github-action to commit SHA

💡 Result:

The SonarSource sonarcloud-github-action (SonarSource/sonarcloud-github-action) is deprecated and archived as of October 2025. SonarSource recommends migrating to the unified SonarSource/sonarqube-scan-action, which supports both SonarQube Server and SonarCloud. GitHub Actions best practices require pinning third-party actions to a full-length commit SHA for security, as tags are mutable and vulnerable to supply chain attacks. GitHub now supports organization-level policies enforcing SHA pinning. To pin: 1. Go to the action's GitHub repository: https://github.com/SonarSource/sonarqube-scan-action/releases 2. Select the desired release tag (e.g., v7.1.0, latest as of 2026-04-01). 3. Click the commit SHA next to the tag (full 40-character hash). 4. Copy the ref: SonarSource/sonarqube-scan-action@ # v7.1.0 Example workflow step (for SonarCloud): - name: SonarQube Scan uses: SonarSource/sonarqube-scan-action@ffc3010 # v7.1.0 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > -Dsonar.organization=your-org -Dsonar.projectKey=your-project For the deprecated sonarcloud-github-action, last release v5.0.0 commit is ffc3010 (from workflow), but do not use it. Update with Dependabot (github-actions ecosystem) or tools like pinact for bulk pinning. Verify SHA is from the official repo, not a fork. Official docs confirm using sonarqube-scan-action@v7 (tag), but replace with SHA per security best practices.

Citations:


GitHub Action을 commit SHA로 고정하세요.

Line 64의 SonarSource/sonarcloud-github-action@master는 업스트림 변경에 따라 비결정적 실행과 공급망 보안 위험을 초래합니다. 릴리스 태그도 변경 가능하므로, commit SHA(예: @ffc3010b5a0d9a5b0e5a5b0e5a5b0e5a5b0e5a5b)로 고정하여 불변성을 보장하세요.

참고: 이 Action은 2025년 10월부터 deprecated되었으므로, 장기적으로는 SonarSource/sonarqube-scan-action으로 마이그레이션을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/sonarcloud-analysis/references/sonarcloud-setup.md at line
64, Replace the non-deterministic reference
SonarSource/sonarcloud-github-action@master with a pinned commit SHA (e.g.,
SonarSource/sonarcloud-github-action@<commit-sha>) to ensure immutable workflow
execution; locate the `uses: SonarSource/sonarcloud-github-action@master` entry
and swap the tag for a specific commit SHA, and consider updating the workflow
to use the newer `SonarSource/sonarqube-scan-action` in the long term since the
current action is deprecated.

Comment on lines +15 to +16
SONAR_PROJECT_KEY=koin_web_recode
SONAR_TOKEN=your-personal-access-token # sonarcloud.io > My Account > Security
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

SONAR_PROJECT_KEY 예시값이 다른 문서와 충돌합니다.

Line 15의 koin_web_recodeBCSDLab_KOIN_WEB_RECODE 기반 안내(예: setup 문서/sonar-project.properties)와 불일치합니다. 동일 키 규칙으로 통일하지 않으면 API 조회 실패 원인이 됩니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/sonarcloud-analysis/SKILL.md around lines 15 - 16, 예시값
SONAR_PROJECT_KEY의 불일치 문제: 현재 샘플 값 "koin_web_recode"를 프로젝트에서 통용되는 키 규칙으로 통일된 값인
"BCSDLab_KOIN_WEB_RECODE"로 변경하고, SONAR_PROJECT_KEY를 참조하는 다른 문서(예: setup 문서,
sonar-project.properties)와 동일하게 맞춰 동기화하세요; 해당 키를 사용하는 모든 설정/스크립트에서 변수
이름(SONAR_PROJECT_KEY)과 값이 일치하는지 확인해 수정하면 API 조회 실패를 방지할 수 있습니다.

Copy link
Copy Markdown
Contributor

@ff1451 ff1451 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

@dooohun dooohun merged commit 74e357d into develop Apr 21, 2026
4 checks passed
@github-actions github-actions Bot deleted the chore/sonarcloud-integration branch April 21, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🌏 Deploy 배포 관련 사항

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants